<template>
  <view class="container">
    <uni-card>
      <!-- 搜索区域 -->
      <view class="uni-search">
        <uni-search-bar
          v-model="queryParams.menuName"
          placeholder="请输入菜单名称"
          @confirm="handleQuery"
        />
      </view>
      
      <!-- 操作按钮区域 -->
      <view class="uni-group">
        <button type="primary" @click="handleAdd" size="mini">新增</button>
      </view>

      <!-- 列表区域 - 使用树形结构 -->
      <view class="menu-tree">
        <view 
          v-for="(item, index) in menuList" 
          :key="index" 
          class="menu-item"
        >
          <view class="menu-header" @click="toggleMenu(item)">
            <view class="menu-icon">
              <uni-icons type="folder" size="20" v-if="item.menuType === 'M'"></uni-icons>
              <uni-icons type="list" size="20" v-else-if="item.menuType === 'C'"></uni-icons>
              <uni-icons type="checkbox" size="20" v-else></uni-icons>
            </view>
            <view class="menu-title">{{ item.menuName }}</view>
            <view class="menu-status" :class="item.status === '0' ? 'status-normal' : 'status-disabled'">
              {{ item.status === '0' ? '正常' : '停用' }}
            </view>
            <view class="menu-actions">
              <button type="primary" size="mini" @click.stop="handleUpdate(item)" class="action-btn">修改</button>
              <button type="warn" size="mini" @click.stop="handleDelete(item)" class="action-btn">删除</button>
              <button type="default" size="mini" @click.stop="handleAdd(item)" class="action-btn">新增</button>
            </view>
            <view class="menu-expand" v-if="item.children && item.children.length">
              <uni-icons :type="item.open ? 'arrow-down' : 'arrow-right'" size="18"></uni-icons>
            </view>
          </view>
          
          <!-- 子菜单 -->
          <view class="submenu" v-if="item.open && item.children && item.children.length">
            <view 
              v-for="(subItem, subIndex) in item.children" 
              :key="'sub-'+index+'-'+subIndex" 
              class="menu-item submenu-item"
            >
              <view class="menu-header">
                <view class="menu-icon">
                  <uni-icons type="list" size="20" v-if="subItem.menuType === 'C'"></uni-icons>
                  <uni-icons type="checkbox" size="20" v-else></uni-icons>
                </view>
                <view class="menu-title">{{ subItem.menuName }}</view>
                <view class="menu-path" v-if="subItem.path">{{ subItem.path }}</view>
                <view class="menu-perms" v-if="subItem.perms">{{ subItem.perms }}</view>
                <view class="menu-status" :class="subItem.status === '0' ? 'status-normal' : 'status-disabled'">
                  {{ subItem.status === '0' ? '正常' : '停用' }}
                </view>
                <view class="menu-actions">
                  <button type="primary" size="mini" @click.stop="handleUpdate(subItem)" class="action-btn">修改</button>
                  <button type="warn" size="mini" @click.stop="handleDelete(subItem)" class="action-btn">删除</button>
                  <button type="default" size="mini" @click.stop="handleAdd(subItem)" class="action-btn">新增</button>
                </view>
              </view>
              
              <!-- 按钮权限 -->
              <view class="submenu" v-if="subItem.children && subItem.children.length">
                <view 
                  v-for="(btnItem, btnIndex) in subItem.children" 
                  :key="'btn-'+index+'-'+subIndex+'-'+btnIndex" 
                  class="menu-item button-item"
                >
                  <view class="menu-header">
                    <view class="menu-icon">
                      <uni-icons type="checkbox" size="20"></uni-icons>
                    </view>
                    <view class="menu-title">{{ btnItem.menuName }}</view>
                    <view class="menu-perms" v-if="btnItem.perms">{{ btnItem.perms }}</view>
                    <view class="menu-status" :class="btnItem.status === '0' ? 'status-normal' : 'status-disabled'">
                      {{ btnItem.status === '0' ? '正常' : '停用' }}
                    </view>
                    <view class="menu-actions">
                      <button type="primary" size="mini" @click.stop="handleUpdate(btnItem)" class="action-btn">修改</button>
                      <button type="warn" size="mini" @click.stop="handleDelete(btnItem)" class="action-btn">删除</button>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </uni-card>

    <!-- 添加或修改菜单弹窗 -->
    <uni-popup ref="popup" type="dialog">
      <uni-popup-dialog
        :title="title"
        mode="input"
        :value="form.menuName"
        placeholder="请输入菜单名称"
        @confirm="submitForm"
      >
        <uni-forms ref="form" :model="form" :rules="rules">
          <uni-forms-item label="菜单名称" required name="menuName">
            <uni-easyinput v-model="form.menuName" placeholder="请输入菜单名称"/>
          </uni-forms-item>
          <uni-forms-item label="显示顺序" required name="orderNum">
            <uni-easyinput v-model="form.orderNum" type="number" placeholder="请输入显示顺序"/>
          </uni-forms-item>
          <uni-forms-item label="权限标识" name="perms">
            <uni-easyinput v-model="form.perms" placeholder="请输入权限标识"/>
          </uni-forms-item>
          <uni-forms-item label="路由地址" name="path">
            <uni-easyinput v-model="form.path" placeholder="请输入路由地址"/>
          </uni-forms-item>
          <uni-forms-item label="组件路径" name="component">
            <uni-easyinput v-model="form.component" placeholder="请输入组件路径"/>
          </uni-forms-item>
          <uni-forms-item label="菜单类型" required name="menuType">
            <uni-data-checkbox
              v-model="form.menuType"
              :localdata="[
                {text: '目录', value: 'M'},
                {text: '菜单', value: 'C'},
                {text: '按钮', value: 'F'}
              ]"
            />
          </uni-forms-item>
          <uni-forms-item label="菜单状态" name="status">
            <uni-data-checkbox
              v-model="form.status"
              :localdata="[
                {text: '正常', value: '0'},
                {text: '停用', value: '1'}
              ]"
            />
          </uni-forms-item>
        </uni-forms>
      </uni-popup-dialog>
    </uni-popup>
  </view>
</template>

<script>
import { listMenu, getMenu, delMenu, addMenu, updateMenu } from '@/api/system/menu'

export default {
  data() {
    return {
      // 遮罩层
      loading: true,
      // 菜单列表
      menuList: [],
      // 弹出层标题
      title: "",
      // 查询参数
      queryParams: {
        menuName: undefined,
        status: undefined
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        menuName: {
          rules: [{
            required: true,
            errorMessage: '菜单名称不能为空'
          }]
        },
        orderNum: {
          rules: [{
            required: true,
            errorMessage: '显示顺序不能为空'
          }]
        },
        menuType: {
          rules: [{
            required: true,
            errorMessage: '菜单类型不能为空'
          }]
        }
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询菜单列表 */
    getList() {
      this.loading = true;
      listMenu(this.queryParams).then(response => {
        this.menuList = this.handleTree(response.data, "menuId");
        // 初始化所有目录为关闭状态
        this.menuList.forEach(item => {
          this.$set(item, 'open', false);
        });
        this.loading = false;
      });
    },
    /** 切换菜单展开/折叠状态 */
    toggleMenu(item) {
      this.$set(item, 'open', !item.open);
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.getList();
    },
    /** 新增按钮操作 */
    handleAdd(row) {
      this.reset();
      this.title = "添加菜单";
      if (row != null && row.menuId) {
        this.form.parentId = row.menuId;
      }
      this.$refs.popup.open();
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getMenu(row.menuId).then(response => {
        this.form = response.data;
        this.title = "修改菜单";
        this.$refs.popup.open();
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs.form.validate().then(res => {
        if (this.form.menuId != undefined) {
          updateMenu(this.form).then(response => {
            this.$modal.msgSuccess("修改成功");
            this.$refs.popup.close();
            this.getList();
          });
        } else {
          addMenu(this.form).then(response => {
            this.$modal.msgSuccess("新增成功");
            this.$refs.popup.close();
            this.getList();
          });
        }
      }).catch(error => {
        console.log('表单错误信息：', error);
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      uni.showModal({
        title: '提示',
        content: '是否确认删除名称为"' + row.menuName + '"的数据项?',
        success: res => {
          if (res.confirm) {
            delMenu(row.menuId).then(() => {
              this.getList();
              this.$modal.msgSuccess("删除成功");
            })
          }
        }
      });
    },
    // 表单重置
    reset() {
      this.form = {
        menuId: undefined,
        parentId: undefined,
        menuName: undefined,
        orderNum: undefined,
        path: undefined,
        component: undefined,
        perms: undefined,
        menuType: 'M',
        status: '0'
      };
    },
    // 构造树型结构数据
    handleTree(data, id) {
      let config = {
        id: id || 'id',
        parentId: 'parentId',
        childrenList: 'children'
      };
      var childrenListMap = {};
      var nodeIds = {};
      var tree = [];
      for (let d of data) {
        let parentId = d[config.parentId];
        if (childrenListMap[parentId] == null) {
          childrenListMap[parentId] = [];
        }
        nodeIds[d[config.id]] = d;
        childrenListMap[parentId].push(d);
      }
      for (let d of data) {
        let parentId = d[config.parentId];
        if (nodeIds[parentId] == null) {
          tree.push(d);
        }
      }
      for (let t of tree) {
        adaptToChildrenList(t);
      }
      function adaptToChildrenList(o) {
        if (childrenListMap[o[config.id]] !== null) {
          o[config.childrenList] = childrenListMap[o[config.id]];
        }
        if (o[config.childrenList]) {
          for (let c of o[config.childrenList]) {
            adaptToChildrenList(c);
          }
        }
      }
      return tree;
    }
  }
};
</script>

<style lang="scss" scoped>
.container {
  padding: 20rpx;
}
.uni-search {
  padding: 10rpx 0;
}
.uni-group {
  margin: 20rpx 0;
  display: flex;
  justify-content: flex-end;
}
.menu-tree {
  margin-top: 15px;
}

.menu-item {
  border-bottom: 1px solid #eee;
}

.menu-header {
  display: flex;
  align-items: center;
  padding: 12px 0;
  position: relative;
}

.menu-icon {
  margin-right: 10px;
  display: flex;
  align-items: center;
}

.menu-title {
  flex: 1;
  font-weight: bold;
  font-size: 14px;
}

.menu-path, .menu-perms {
  color: #999;
  font-size: 11px;
  margin-right: 10px;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-status {
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
  margin-right: 10px;
}

.status-normal {
  background-color: #e8f7e9;
  color: #67c23a;
}

.status-disabled {
  background-color: #f4f4f5;
  color: #909399;
}

.menu-actions {
  display: flex;
  align-items: center;
  gap: 5px;
}

.action-btn {
  padding: 0 8px;
  height: 24px;
  line-height: 24px;
  font-size: 11px;
  margin-left: 0 !important;
}

.menu-expand {
  margin-left: 10px;
}

.submenu {
  padding-left: 20px;
  border-left: 1px dashed #eee;
  margin-left: 10px;
}

.submenu-item {
  border-bottom: 1px dashed #eee;
}

.button-item {
  border-bottom: none;
}

.button-item:last-child {
  padding-bottom: 10px;
}

// 子菜单样式调整
.submenu .menu-title {
  font-size: 13px;
  font-weight: normal;
}

// 按钮项样式调整
.button-item .menu-title {
  font-size: 12px;
  color: #606266;
}

// 美化卡片样式
:deep(.uni-card) {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-radius: 8px;
}

// 美化搜索框
:deep(.uni-searchbar) {
  padding: 5px 0;
}

// 美化按钮悬停效果
button.action-btn:active {
  opacity: 0.8;
}
</style> 